package com.fpinjava.functions.exercise02_06;


public interface Function<T, U> {

  U apply(T arg);  // T ->U 为 T到U的映射关系

  static <T, U, V> Function<Function<U, V>, Function<Function<T, U>, Function<T, V>>> higherCompose() {
    //(U,V)->((T,U),(T,V))  f为(U,V)到((T,U),(T,V)) 映射关系
    //(T,U)->(T,V) g 为(T,U)到(T,V)映射关系
    // T-V x 为T到V的映射关系
    return (Function<U,V> f) -> (Function<T,U> g) -> (T x) -> f.apply(g.apply(x));
  }

  static <T, U, V> Function<Function<T, U>, Function<Function<U, V>, Function<T, V>>> higherAndThen() {
    //(T,U)->((U,V),(T,V))  f为(T,U)到((U,V),(T,V)) 映射关系
    // (U，V)->(T,V)   g为 (U，V) 到（T,V）的映射关系
    // T ->V z 为T到V的映射关系
    return (Function<T,U> f) -> (Function<U,V> g) -> ( T z) -> g.apply(f.apply(z));
  }

  /*
   * higherAndThen may of course also be defined in terms of higherCompose.
   */
  static <T, U, V> Function<Function<T, U>, Function<Function<U, V>, Function<T, V>>> higherAndThen2() {
    //(T,U) -> ((U,V),(T,V)) f 为（T,U）到 ((U,V),(T,V))的映射关系
    // (U,V)-> (T,V) g 为  (U,V) 到 （T，V）的映射关系
    return (Function<T,U> f) -> (Function<U,V> g) -> Function.<T, U, V>higherCompose().apply(g).apply(f);
  }
}
